package com.engine.zzworkflow.cmd;

import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.User;

import java.util.HashMap;
import java.util.Map;

/**
 * 抛送单据数据到会计引擎生成凭证
 */
public class SendBusinessCmd extends AbstractCommonCommand<Map<String,Object>> {

    public SendBusinessCmd(User user, Map<String, Object> params) {
        this.params = params;
        this.user =user;
    }

    @Override
    public BizLogContext getLogContext() {
        return null;
    }

    @Override
    public Map<String, Object> execute(CommandContext commandContext) {

        Map<String,Object> apidatas  = new HashMap<>();
        apidatas.put("api_status", false);

        //流程requestid
        String requestid = Util.null2String(params.get("requestid"));
        //流程workflowid
        String workflowid = Util.null2String(params.get("workflowid"));
        //会计引擎凭证模板ID
       // String businessTypeId = Util.null2String(params.get("businessTypeId"));
        //当前单据回写时凭证信息是明细
        String mx = Util.null2String(params.get("mx"));
        RecordSet rs = new RecordSet();
        String tablename = getWfTablenamById(workflowid, rs);
        if("".equals(tablename)) {
            writeLog("获取流程表名失败");
            apidatas.put("err", "获取流程表名失败");
            return apidatas;
        }

        BaseBean bb = new BaseBean();
        String url = bb.getPropValue("zzflowbusinessurl", "receiveDataurl");
        if("".equals(url)) {
            writeLog("抛送会计引擎接口地址配置文件未配置");
            apidatas.put("err", "抛送会计引擎接口地址配置文件未配置");
            return apidatas;
        }
       /* if("".equals(businessTypeId)) {
            writeLog("会计引擎凭证模板id,businessTypeId未配置");
            apidatas.put("err", "会计引擎凭证模板id,businessTypeId未配置");
            return apidatas;
        }*/
        writeLog("抛送会计引擎接口地址配url："+url);
        Map<String ,String> map=getSendParams(tablename, requestid, mx);
        String sendParams = map.get("params");
        writeLog("请求参数sendParams："+sendParams);

        String bdh=map.get("bdh");

        String res = sendJson(url, sendParams);
        JSONObject resObj = JSONObject.fromObject(res);
        writeLog("res:"+res);
        if(resObj.containsKey("statusCode")
                && "200".equals(resObj.getString("statusCode"))) {
            apidatas.put("api_status", true);
            apidatas.put("res", resObj.getString("responseBosy"));
            RecordSet recordSet=new RecordSet();
            String userName=changeField(String.valueOf(user.getUID()),"hrmresource", "id", "workcode", recordSet);;
            if(userName==null || userName.equals("")){
                userName="admin";
            }
            String openBusinessUrl="http://172.21.182.242:8880/business/receiveData/getPrefaUrl?userName="+userName+"&businessDataId="+bdh;
            String resGet=getJson(openBusinessUrl);
            JSONObject resObjGet = JSONObject.fromObject(resGet);
            apidatas.put("data", resObjGet.getString("responseBosy"));
        }else {
            apidatas.put("api_status", false);
            apidatas.put("statusCode", resObj.getString("statusCode"));
            apidatas.put("err", resObj.getString("err"));
        }

        return apidatas;
    }

    /**
     * 获取接口请求参数
     * @param tablename
     * @param requestid
     * @param mx
     * @return
     */
    private Map<String, String> getSendParams(String tablename, String requestid, String mx) {
        Map<String, String> map = new HashMap<>();
        RecordSet rs = new RecordSet();
        RecordSet rs2 = new RecordSet();

        //获取流程主表数据
        HashMap<String, String> mainData = new HashMap<>();
        mainData.put("mx", mx);
        String mainid = "0";
        String sql = "select id, pzrq,lcbm,tdr,tdrbm, bzgs szgs,zy from "+tablename+" where requestid = ?";
        boolean b = rs.executeQuery(sql, requestid);
        if(b && rs.next()) {
            mainid = rs.getString("id");
            //凭证日期	pzrq	凭证日期	凭证日期	pzrq
            String pzrq = Util.null2String(rs.getString("pzrq"));
            mainData.put("pzrq", pzrq);
            //流程编码	lcbm	备选参考编号	表单号	bdh
            String bdh = Util.null2String(rs.getString("lcbm"));
            mainData.put("bdh", bdh);
            map.put("bdh", bdh);
            //填单人	tdr	经办人（不传浪潮，返回到表单凭证明细）	报账人	bzr
            String bzr = Util.null2String(rs.getString("tdr"));
            bzr = changeField(bzr,"hrmresource", "id", "workcode", rs2);
            mainData.put("bzr", bzr);
            //填单人部门	tdrbm	经办人部门（不传浪潮，返回到表单凭证明细）	报账部门	bzbm
            String bzbm = Util.null2String(rs.getString("tdrbm"));
            bzbm = changeField(bzbm,"hrmdepartment", "id", "departmentcode", rs2);
            mainData.put("bzbm", bzbm);
            //所属公司	szgs	经办人公司（不传浪潮，返回到表单凭证明细）	所属公司编码	szgsbm
            String szgsbm = Util.null2String(rs.getString("szgs"));
            szgsbm = changeField(szgsbm,"hrmsubcompany", "id", "subcompanycode", rs2);
            mainData.put("szgsbm", szgsbm);
            //摘要	zy	头摘要	摘要	zy
            String zy = Util.null2String(rs.getString("zy"));
            mainData.put("zy", zy);
            mainData.put("pid", "zz");
        }

        //接口入参
        JSONArray params = new JSONArray();
        sql = "select hszt,bz,hl,xzy hzy,gdlx,ks,htbh ht,czfs,hsywfl,xm,yglx,gr,yhzh,yhlb,bm,nbwlgsd,tzdx,kjxm," +
                "pz,jfje,dfje,jfwb,dfwb from "+tablename+"_dt1 where mainid = ?";
        boolean b1 = rs.executeQuery(sql, mainid);
        while (b1 && rs.next()) {
            Map<String, String> dt1data = new HashMap<>();
            dt1data.putAll(mainData);
            //入账主体	hszt	核算主体	核算主体编码	hsztbm
            String hsztbm = Util.null2String(rs.getString("hszt"));
            hsztbm = changeField(hsztbm,"uf_jccs_zt ", "id", "ztbm", rs2);
            dt1data.put("hsztbm", hsztbm);
            //币种	bz	货币编码	货币编码	cny
            String cny = Util.null2String(rs.getString("bz"));
            cny = changeField(cny,"ctrip_CurrencyType", "id", "UnKnow", rs2);
            dt1data.put("cny", cny);
            //汇率	hl	汇率	汇率	huilv
            String huilv = Util.null2String(rs.getString("hl"));
            dt1data.put("huilv", huilv);
            //行摘要	hzy	行摘要	行摘要	hzy
            String hzy = Util.null2String(rs.getString("hzy"));
            dt1data.put("hzy", hzy);
            //股东类型	gdlx	股东类型	股东类型	gdlx
            String gdlx = Util.null2String(rs.getString("gdlx"));
            gdlx = changeField(gdlx,"uf_jccs_dgwldx", "id", "wldxbm", rs2);
            dt1data.put("gdlx", gdlx);
            //客商	ks	客商	客商	ks
            String ks = Util.null2String(rs.getString("ks"));
            ks = changeField(ks,"uf_jccs_dgwldx", "id", "wldxbm", rs2);
            dt1data.put("ks", ks);
            //合同	ht	合同	合同	ht
            String ht = Util.null2String(rs.getString("ht"));
            ht = changeField(ht,"uf_zchttz", "id", "htbh", rs2);
            dt1data.put("ht", ht);
            //出资方式	czfs	出资方式	出资方式	czfs
            String czfs = Util.null2String(rs.getString("czfs"));
            czfs=czfsbm(czfs);
            dt1data.put("czfs", czfs);
            //核算业务分类	hsywfl	核算业务分类	核算业务分类	hsywfl
            String hsywfl = Util.null2String(rs.getString("hsywfl"));
            hsywfl = changeField(hsywfl,"uf_jccs_hsywfl", "id", "dm", rs2);
            dt1data.put("hsywfl", hsywfl);
            //项目	xm	项目	项目	xm
            String xm = Util.null2String(rs.getString("xm"));
            xm = changeField(xm,"uf_jccs_yskmysxmywlx", "id", "yskmbm", rs2);
            dt1data.put("xm", xm);
            //员工类型	yglx	员工类型	员工类型	yglx
            String yglx = Util.null2String(rs.getString("yglx"));
            yglx = changeField(yglx,"uf_jccs_yglx", "id", "bh", rs2);
            dt1data.put("yglx", yglx);
            //个人	gr	个人	个人	gr
            String gr = Util.null2String(rs.getString("gr"));
            gr = changeField(gr,"hrmresource", "id", "workcode", rs2);
            dt1data.put("gr", gr);
            //银行账户	yhzh	银行账户	银行账户	yhzh
            String yhzh = Util.null2String(rs.getString("yhzh"));
            yhzh = changeField(yhzh,"uf_yhzhxxb", "id", "yhzh", rs2);
            dt1data.put("yhzh", yhzh);
            //银行类别	yhlb	银行类别	银行类别	yhlb
            String yhlb = Util.null2String(rs.getString("yhlb"));
            yhlb = changeField(yhlb,"uf_jccs_yhlb", "id", "bh", rs2);
            dt1data.put("yhlb", yhlb);
            //部门	bm	部门	部门	bm
            String bm = Util.null2String(rs.getString("bm"));
            bm = changeField(bm,"hrmdepartment", "id", "departmentcode", rs2);
            dt1data.put("bm", bm);
            //内部往来公司段	nbwlgsd	内部外来公司段	内部往来公司段	nbwlgsd
            String nbwlgsd = Util.null2String(rs.getString("nbwlgsd"));
            nbwlgsd = changeField(nbwlgsd,"uf_jccs_dgwldx", "id", "wldxbm", rs2);
            dt1data.put("nbwlgsd", nbwlgsd);
            //tzdx	投资对象	投资对象	tzdx
            String tzdx = Util.null2String(rs.getString("tzdx"));
            nbwlgsd = changeField(nbwlgsd,"uf_jccs_dgwldx", "id", "wldxbm", rs2);
            dt1data.put("tzdx", tzdx);
            //科技项目	kjxm	科技项目	科技项目	kjxm
            String kjxm = Util.null2String(rs.getString("kjxm"));
            kjxm = changeField(kjxm,"uf_jccs_kjxm", "id", "xmdm", rs2);
            dt1data.put("kjxm", kjxm);
            //品种	pz	品种	品种	pz
            String pz = Util.null2String(rs.getString("pz"));
            pz = changeField(pz,"uf_jccs_pz", "id", "bh", rs2);
            dt1data.put("pz", pz);
            //借方金额	jfje	金额	借方金额	jfje
            String jfje = Util.null2String(rs.getString("jfje"));
            dt1data.put("jfje", jfje);
            //贷方金额	dfje	金额	贷方金额	dfje
            String dfje = Util.null2String(rs.getString("dfje"));
            dt1data.put("dfje", dfje);
            //借方外币	jfwb	金额	借方外币金额	jfwbje
            String jfwbje = Util.null2String(rs.getString("jfwb"));
            dt1data.put("jfwbje", jfwbje);
            //贷方外币	dfwb	金额	贷方外币金额	dfwbje
            String dfwbje = Util.null2String(rs.getString("dfwb"));
            dt1data.put("dfwbje", dfwbje);
            params.add(dt1data);
        }
        map.put("params", params.toString());
        return map;
    }


    /**
     * 根据workflowid 获取流程表单名称
     * @param workflowid
     * @param rs
     * @return
     */
    private String getWfTablenamById(String workflowid, RecordSet rs) {
        String sql = "select t2.tablename from workflow_base t1 " +
                "left join workflow_bill t2 on t1.formid = t2.id where t1.id = ?";
        boolean b = rs.executeQuery(sql, workflowid);
        if(b && rs.next()) {
            return Util.null2String(rs.getString(1));
        }else {
            return "";
        }
    }

    /**
     * 字段转换
     * @param value
     * @param tablename
     * @param oldField
     * @param newField
     * @param rs
     * @return
     */
    private String changeField(String value, String tablename, String oldField, String newField, RecordSet rs) {
        String sql = "select "+newField+" from "+tablename+" where "+oldField+" = ?";
        boolean b = rs.executeQuery(sql, Util.null2String(value));
        if(b && rs.next()) {
            return Util.null2String(rs.getString(1));
        }else {
            return "";
        }
    }

    /**
     * 发送post请求
     * @param targetUrl
     * @param jsonParams
     * @return
     */
    private String sendJson(String targetUrl, String jsonParams) {
        JSONObject res = new JSONObject();
        res.put("err", "");
        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(targetUrl);
            StringEntity entity = new StringEntity(jsonParams);
            entity.setContentType("application/json;charset=UTF-8");
            httpPost.setEntity(entity);

            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            res.put("statusCode", statusCode);

            String responseBody = EntityUtils.toString(response.getEntity());
            res.put("responseBosy", responseBody);
            httpClient.close();

            return res.toString();

        } catch (Exception e) {
            res.put("err", e.getMessage());
            writeLog("抛送会计引擎接口调用失败...message:"+e.getMessage(), e);
            return res.toString();
        }
    }
    private String czfsbm(String czfs){
        if(czfs.equals("1000003")){
            return "内部出资";
        }else if(czfs.equals("1000004")){
            return "外部出资";
        }else if(czfs.equals("1000005")){
            return "内外部联合出资";
        }else{
            return "";
        }
    }

    /**
     * 发送get请求
     * @param targetUrl
     * @param
     * @return
     */
    private String getJson(String targetUrl) {
        JSONObject res = new JSONObject();
        res.put("err", "");
        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(targetUrl);
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
            httpGet.setConfig(requestConfig);
            //3.使用httpClient发起请求并响应获取repsonse
            CloseableHttpResponse response =  httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            res.put("statusCode", statusCode);

            String responseBody = EntityUtils.toString(response.getEntity());
            res.put("responseBosy", responseBody);
            httpClient.close();

            return res.toString();

        } catch (Exception e) {
            res.put("err", e.getMessage());
            writeLog("查看接口调用失败...message:"+e.getMessage(), e);
            return res.toString();
        }
    }
}
